package services

import (
	"context"
	"log"
	"time"

	"demo2/server/storage"

	"github.com/google/uuid"
)

// ChatService 聊天服务
type ChatService struct {
	store      *storage.RedisStore
	llmService *LLMService
}

// NewChatService 创建新的聊天服务
func NewChatService(store *storage.RedisStore, llmService *LLMService) *ChatService {
	return &ChatService{
		store:      store,
		llmService: llmService,
	}
}

// Close 关闭服务
func (c *ChatService) Close() error {
	return c.llmService.Close()
}

// SendMessage 发送消息并获取回复
func (c *ChatService) SendMessage(ctx context.Context, sessionID, userMessage string) (*storage.Message, error) {
	log.Printf("[CHAT-SERVICE] 📨 收到发送消息请求，会话ID: %s, 消息: %s", sessionID, userMessage)
	
	// 保存用户消息
	userMsg := &storage.Message{
		ID:        uuid.New().String(),
		SessionID: sessionID,
		Role:      "user",
		Content:   userMessage,
		Timestamp: time.Now(),
	}

	log.Printf("[CHAT-SERVICE] 💾 保存用户消息到存储，消息ID: %s", userMsg.ID)
	if err := c.store.SaveMessage(ctx, userMsg); err != nil {
		log.Printf("[CHAT-SERVICE] ❌ 保存用户消息失败: %v", err)
		return nil, err
	}

	// 获取历史消息用于上下文
	log.Printf("[CHAT-SERVICE] 📚 获取最近10条历史消息作为上下文...")
	recentMessages, err := c.store.GetRecentMessages(ctx, sessionID, 10)
	if err != nil {
		log.Printf("[CHAT-SERVICE] ❌ 获取历史消息失败: %v", err)
		return nil, err
	}
	log.Printf("[CHAT-SERVICE] 📚 获取到 %d 条历史消息", len(recentMessages))

	// 转换为DeepSeek消息格式
	llmMessages := make([]DeepSeekMessage, 0, len(recentMessages))
	for _, msg := range recentMessages {
		llmMessages = append(llmMessages, DeepSeekMessage{
			Role:    msg.Role,
			Content: msg.Content,
		})
	}
	log.Printf("[CHAT-SERVICE] 🔄 转换为LLM消息格式完成，消息数量: %d", len(llmMessages))

	// 生成AI回复
	log.Printf("[CHAT-SERVICE] 🤖 调用LLM服务生成回复...")
	aiResponse, err := c.llmService.GenerateResponse(ctx, llmMessages)
	if err != nil {
		log.Printf("[CHAT-SERVICE] ❌ LLM服务生成回复失败: %v", err)
		return nil, err
	}
	log.Printf("[CHAT-SERVICE] ✅ LLM服务生成回复成功，响应长度: %d", len(aiResponse))

	// 保存AI回复
	aiMsg := &storage.Message{
		ID:        uuid.New().String(),
		SessionID: sessionID,
		Role:      "assistant",
		Content:   aiResponse,
		Timestamp: time.Now(),
	}

	log.Printf("[CHAT-SERVICE] 💾 保存AI回复到存储，消息ID: %s", aiMsg.ID)
	if err := c.store.SaveMessage(ctx, aiMsg); err != nil {
		log.Printf("[CHAT-SERVICE] ❌ 保存AI回复失败: %v", err)
		return nil, err
	}

	log.Printf("[CHAT-SERVICE] ✅ 消息处理完成，返回AI回复")
	return aiMsg, nil
}

// SendStreamMessage 发送消息并获取流式回复
func (c *ChatService) SendStreamMessage(ctx context.Context, sessionID, userMessage string, responseChan chan<- string) error {
	// 保存用户消息
	userMsg := &storage.Message{
		ID:        uuid.New().String(),
		SessionID: sessionID,
		Role:      "user",
		Content:   userMessage,
		Timestamp: time.Now(),
	}

	if err := c.store.SaveMessage(ctx, userMsg); err != nil {
		return err
	}

	// 获取历史消息用于上下文
	recentMessages, err := c.store.GetRecentMessages(ctx, sessionID, 10)
	if err != nil {
		return err
	}

	// 转换为DeepSeek消息格式
	llmMessages := make([]DeepSeekMessage, 0, len(recentMessages))
	for _, msg := range recentMessages {
		llmMessages = append(llmMessages, DeepSeekMessage{
			Role:    msg.Role,
			Content: msg.Content,
		})
	}

	// 创建一个通道来收集完整的响应
	fullResponseChan := make(chan string, 100)
	fullResponse := ""

	// 启动goroutine来生成流式回复
	go func() {
		defer func() {
			// 安全关闭通道
			select {
			case <-fullResponseChan:
			default:
				close(fullResponseChan)
			}
		}()
		if err := c.llmService.GenerateStreamResponse(ctx, llmMessages, fullResponseChan); err != nil {
			// 如果流式响应失败，发送错误信息
			select {
			case responseChan <- "抱歉，处理您的请求时出现了错误。":
			case <-ctx.Done():
			}
		}
	}()

	// 转发响应并收集完整内容
	for chunk := range fullResponseChan {
		fullResponse += chunk
		select {
		case responseChan <- chunk:
		case <-ctx.Done():
			return ctx.Err()
		}
	}

	// 保存完整的AI回复
	if fullResponse != "" {
		aiMsg := &storage.Message{
			ID:        uuid.New().String(),
			SessionID: sessionID,
			Role:      "assistant",
			Content:   fullResponse,
			Timestamp: time.Now(),
		}

		// 异步保存，不阻塞响应
		go func() {
			c.store.SaveMessage(context.Background(), aiMsg)
		}()
	}

	return nil
}

// GetHistory 获取聊天历史
func (c *ChatService) GetHistory(ctx context.Context, sessionID string) ([]*storage.Message, error) {
	return c.store.GetMessages(ctx, sessionID)
}

// ClearHistory 清除聊天历史
func (c *ChatService) ClearHistory(ctx context.Context, sessionID string) error {
	return c.store.ClearMessages(ctx, sessionID)
}
